import { ElTable } from 'element-plus';
import Menu from '@/model/common/menu';

/**
 * 获取第一个默认激活的路由，菜单展开的路径
 * @param tree 树形结构的菜单列表
 */
export function getCurrentIndexPath(tree: Array<Menu>): Array<string> {
  const path = [] as Array<string>;
  if (tree.length) {
    const menu = tree[0];
    if (menu) {
      if (menu.children && menu.children.length) {
        path.push(menu.id);
        const childrenPath = getCurrentIndexPath(menu.children);
        childrenPath.forEach((item: string) => path.push(item));
        return path;
      }
      path.push(menu.url);
      return path;
    }
  }
  return path as Array<string>;
}

/**
 * 递归出所有菜单的路径
 * @param tree 树形结构的菜单列表
 */
export function listIndexPath(tree: Array<Menu>): Array<Array<string>> {
  const paths = [] as Array<Array<string>>;
  if (tree.length) {
    tree.forEach((item: Menu) => {
      if (item.children && item.children.length) {
        const childrenIndex = listIndexPath(item.children);
        if (childrenIndex.length) {
          childrenIndex.forEach((childIndex: Array<string>) => {
            const path = [item.id] as Array<string>;
            childIndex.forEach((index: string) => {
              path.push(index);
            });
            paths.push(path);
          });
        }
      } else {
        const path = [] as Array<string>;
        path.push(item.url);
        paths.push(path);
      }
    });
  }
  return paths;
}

/**
 * 从菜单中找到重定向的菜单的路由路径
 * @param tree 树形结构的菜单列表
 * @param redirect 重定向的地址
 */
export function getCurrentIndexPathByRedirect(
  tree: Array<Menu>,
  redirect: string,
): Array<string> {
  const paths = listIndexPath(tree);
  if (paths.length) {
    for (let i = paths.length - 1; i >= 0; i -= 1) {
      if (paths[i].includes(redirect)) {
        return paths[i];
      }
    }
  }
  return [] as Array<string>;
}

/**
 * 获取当前节点下所有子节点
 * @param current 当前节点
 * @param list 菜单列表，平面数组，不能是树形结构
 */
export function listChildren(current: Menu, list: Array<Menu>): Array<Menu> {
  let children: Array<Menu> = [];
  list.forEach((item: Menu) => {
    if (item.parentId === current.id) {
      children.push(item);
      // 向下查找，知道最后一级，一般当类型为按钮时，即为最后一级
      if (item.type !== 2) {
        children = [...children, ...listChildren(item, list)];
      }
    }
  });
  return children;
}

/**
 * 获取当前节点之上所有父节点
 * @param current 当前节点
 * @param list 菜单列表，平面数组，不能是树形结构
 */
export function listParent(current: Menu, list: Array<Menu>): Array<Menu> {
  let parents: Array<Menu> = [];
  if (list.length) {
    list.forEach((item: Menu) => {
      if (item.id === current.parentId) {
        parents.push(item);
        // 向上找，直到id为根节点id‘0’
        if (item.id !== '0') {
          parents = [...parents, ...listParent(item, list)];
        }
      }
    });
  }
  return parents;
}

/**
 * 把树形结构的菜单转为平面数组
 * @param tree
 */
export function toList(tree: Array<Menu>): Array<Menu> {
  let list: Array<Menu> = [];
  if (tree.length) {
    tree.forEach((item: Menu) => {
      list.push(item);
      if (item.children && item.children.length) {
        list = [...list, ...toList(item.children)];
      }
    });
  }
  return list;
}

/**
 * 根据选中的id列出选中的菜单对象
 * @param tree 属性结构的菜单列表
 * @param ids 被选中的菜单id
 */
export function listSelected(tree: Array<Menu>, ids: Array<string>): Array<Menu> {
  let selected: Array<Menu> = [];
  if (!ids.length) {
    return selected;
  }
  if (tree.length) {
    tree.forEach((item: Menu) => {
      if (ids.indexOf(item.id) > -1) {
        selected.push(item);
      }
      if (item.children && item.children.length) {
        const sel = listSelected(item.children, ids);
        selected = [...selected, ...sel];
      }
    });
  }
  return selected;
}

/**
 * 设置树形结构的菜单的选中状态
 * @param tree 属性结构的菜单列表
 * @param ids 被选中的菜单id
 * @param ref table的方法
 */
export function setSelected(
  tree: Array<Menu>,
  ids: Array<string>,
  ref: InstanceType<typeof ElTable> | undefined,
): void {
  if (!ids.length || !ref) {
    return;
  }
  if (tree.length) {
    tree.forEach((item: Menu) => {
      ref.toggleRowSelection(item, ids.indexOf(item.id) > -1);
      if (item.children && item.children.length) {
        setSelected(item.children, ids, ref);
      }
    });
  }
}
